﻿using System;

namespace Delegate_EventAvgs
{
    /// <summary>
    /// 委托——事件 计算类
    /// </summary>
    public class Calaulator
    {
        /// <summary>
        /// 1、定义一个内部事件参数类型CalaulateEventAvgs，用户存放 事件引发时向处理程序传递的 状态信息
        /// </summary>
        public class CalculateEventArgs : EventArgs
        {
            public readonly Int32 x, y;
            public CalculateEventArgs(Int32 x, Int32 y)
            {
                this.x = x;
                this.y = y;
            }
        }

        /// <summary>
        /// 2、申明事件委托  -- 命名规范：以EventHander作为事件委托后缀
        /// </summary>
        /// <param name="sender">事件发送者对象</param>
        /// <param name="e">事件参数类对象</param>
        public delegate void CalaulateEventHandler(object sender, CalculateEventArgs e);

        /// <summary>
        /// 3、定义事件成员    -- 命名规范：以Delegate作为委托后缀
        /// </summary>
        public event CalaulateEventHandler MyCalculate;

        /// <summary>
        /// 4、提供收保护的虚方法，可以又子类覆写来拒绝额监视
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnCalculate(CalculateEventArgs e)
        {
            if (MyCalculate != null)
            {
                MyCalculate(this, e);
            }
        }

        /// <summary>
        /// 5、 进行计算，调用该方法表示有新的计算发生
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void Calculate(Int32 x, Int32 y)
        {
            CalculateEventArgs e = new CalculateEventArgs(x, y);
            //6、通知所有事件的注册者
            OnCalculate(e);
        }

    }
    /// <summary>
    /// 定义事件触发者
    /// </summary>
    public class CalculatorManger
    {
        /// <summary>
        /// 定义消息通知方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void Add(object sender, Calaulator.CalculateEventArgs e)
        {
            Console.WriteLine(e.x + e.y);
        }
        /// <summary>
        /// 定义消息通知方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void Substract(object sender, Calaulator.CalculateEventArgs e)
        {
            Console.WriteLine(e.x - e.y);
        }
    }

    /// <summary>
    /// 事件处理程序
    /// </summary>
    public class Test_Calculate
    {
        static void Main(string[] args)
        {
            Calaulator calaulator = new Calaulator();

            //事件触发者
            CalculatorManger manger = new CalculatorManger();

            //事件绑定
            calaulator.MyCalculate += manger.Add;
            calaulator.MyCalculate += manger.Substract;
            #region Observer模式在委托中的应用
            ///WF窗体的Button1的Click事件就对应事件的响应
            ///this.button1_Click+=new System.EventHander(this.button1_click);
            ///用于将button1_click方法绑定到button1的Click事件上，当有按钮按下时，执行button1_click方法
            ///private void button1_click(object sender, EventArgs e) {   .......  } 
            #endregion
            calaulator.Calculate(300, 100);

            //事件注销
            calaulator.MyCalculate -= manger.Substract;
            calaulator.Calculate(300, 100);

            Console.ReadKey();

        }

    }

}
